﻿using Benefactor.Models.DbModels;
using Benefactor.Services;
using Benefactor.Services.Repositories;
using Bigway.Common.Jobs;
using Bigway.Common.Utils;

namespace Benefactor.Jobs;

using static Statics;

public class BenefitsCardOrderProcessJob(
    IServiceScopeFactory serviceScopeFactory,
    string systemId) : BaseBackgroundJob<BenefitsCardOrderProcessJob>(serviceScopeFactory, systemId)
{
    protected override async Task DoJob(IServiceProvider serviceProvider, 
        ILogger<BenefitsCardOrderProcessJob> logger)
    {
        var crmebOrderRepository = serviceProvider.GetRequiredService<ICrmebOrderRepository>();

        var appConfig = serviceProvider.GetRequiredService<IAppConfig>();
        var benefitsCardMerchantId = int.Parse(appConfig.BenefitsCardMerchantId);

        var crmebOrdersToFulfill = await crmebOrderRepository.GetAllAsync(query =>
            query.Where(x => (x.MerchantId == benefitsCardMerchantId || x.MerchantId == 0) && 
                             x.Status == CrmebOrderPaidStatus)
        );

        if (crmebOrdersToFulfill.Count == 0)
        {
            logger.LogInformation("No paid orders to fulfill");
            return;
        }

        var crmebOrdersMap = crmebOrdersToFulfill.ToDictionary(x => x.OrderNo);
        var merchantOrders = crmebOrdersToFulfill
            .Where(x => !string.IsNullOrEmpty(x.PlatformOrderNo))
            .ToList();

        var orderCount = merchantOrders.Count;
        logger.LogInformation("Found {Count} benefits card order to fulfill",
            orderCount);

        List<CrmebOrder> ordersToUpdate = [];
        foreach (var merchantOrder in merchantOrders)
        {
            merchantOrder.PlatformOrder = crmebOrdersMap.GetValueOrDefault(merchantOrder.PlatformOrderNo);
            ordersToUpdate.Add(merchantOrder);
            if (merchantOrder.PlatformOrder != null)
            {
                ordersToUpdate.Add(merchantOrder.PlatformOrder);
            }
        }

        var chinaNow = DateTimeUtils.ChinaNow;
        
        foreach (var crmebOrder in ordersToUpdate)
        {
            crmebOrder.Status = CrmebOrderCompletedStatus;
            crmebOrder.UpdateTime = chinaNow;
        }

        await crmebOrderRepository.UpdateAllAsync(ordersToUpdate);

        LogCompletion();

        return;

        void LogCompletion()
        {
            logger.LogInformation("Successfully completed {Count} benefits card orders",
                orderCount);
        }
    }
}